<template>
  <div id="mapview" ref="mapview"></div>
</template>

<script setup lang="ts" name="Map">
import { onBeforeMount, onUnmounted } from 'vue'

import AMapLoader from '@amap/amap-jsapi-loader'
import * as OfficeAreaApi from '@/api/area/officeArea'
import * as officeAreaClassApi from '@/api/area/officeAreaClass'
const { push } = useRouter()

export interface MapConfigureInter {
  on: Fn
  destroy?: Fn
  clearEvents?: Fn
  addControl?: Fn
  setCenter?: Fn
  getCenter?: Fn
  setZoom?: Fn
  plugin?: Fn
  clearInfoWindow?: Fn
}

let MarkerCluster
let map: MapConfigureInter

const mapview = ref()
const classList = ref()
const MapConfigure = {
  amapKey: import.meta.env.VITE_AMAP_KEY,
  options: {
    resizeEnable: true,
    center: [116.403963, 39.915119],
    zoom: 14
  }
}

onBeforeMount(async () => {
  window._AMapSecurityConfig = {
    securityJsCode: import.meta.env.VITE_AMAP_SECURITY_KEY
  }

  const { options } = MapConfigure

  const AMap = await AMapLoader.load({
    key: MapConfigure.amapKey,
    version: '2.0',
    plugins: ['AMap.MarkerCluster']
  })
  // 创建地图实例
  map = new AMap.Map(mapview.value, options)

  //地图中添加地图操作ToolBar插件
  map.plugin!(['AMap.ToolBar', 'AMap.MapType'], () => {
    map.addControl!(new AMap.ToolBar())
    //地图类型切换
    map.addControl!(
      new AMap.MapType({
        defaultType: 0
      })
    )
  })

  const areaList = await OfficeAreaApi.simpleList()
  classList.value = await officeAreaClassApi.listQuery()

  MarkerCluster = new AMap.MarkerCluster(map, [], {
    // 聚合网格像素大小
    gridSize: 80,
    maxZoom: 14,
    renderMarker(ctx) {
      const { marker, data } = ctx
      if (Array.isArray(data) && data[0]) {
        const { name } = data[0]
        marker.setLabel({
          direction: 'bottom',
          //设置文本标注偏移量
          offset: new AMap.Pixel(-4, 0),
          //设置文本标注内容
          content: `<div> ${name}</div>`
        })
        // marker.setOffset(new AMap.Pixel(-18, -10))
        marker.on('click', ({ lnglat }) => {
          map.setZoom!(13) //设置地图层级
          //创建 infoWindow 实例
          const infoWindow = new AMap.InfoWindow({
            isCustom: true,
            content: createInfoWindow(data[0]),
            offset: new AMap.Pixel(212, -20)
          })

          infoWindow.open(map, [lnglat.lng, lnglat.lat])
          map.setCenter!(lnglat)
        })
      }
    }
  })

  const points: object = areaList.map((v) => {
    return {
      lnglat: [v.lng, v.lat],
      ...v
    }
  })
  if (MarkerCluster) MarkerCluster.setData(points)
})

//构建自定义信息窗体
function createInfoWindow(areaInfo) {
  var content: string[] = []
  content.push('地址：' + areaInfo.detailAddress)
  content.push('分类：' + classList.value.find((obj) => obj.id === areaInfo.areaClassId).name)
  var info = document.createElement('div')
  info.className = 'custom-info input-card content-window-card'

  //可以通过下面的方式修改自定义窗体的宽高
  info.style.width = '400px'
  // 定义顶部标题
  var top = document.createElement('div')
  var titleD = document.createElement('div')
  var closeX = document.createElement('img')
  top.className = 'info-top'
  titleD.innerHTML = areaInfo.name
  closeX.src = 'https://webapi.amap.com/images/close2.gif'
  closeX.onclick = closeInfoWindow

  top.appendChild(titleD)
  top.appendChild(closeX)
  info.appendChild(top)

  // 定义中部内容
  var middle = document.createElement('div')
  middle.className = 'info-middle'
  middle.innerHTML = content.join('<br/>')
  info.appendChild(middle)

  // 定义中部内容
  var detail = document.createElement('div')
  detail.className = 'info-detail'
  detail.innerHTML = '查看详情'
  detail.onclick = () => pushArea(areaInfo.name)
  info.appendChild(detail)

  // 定义底部内容
  var bottom = document.createElement('div')
  bottom.className = 'info-bottom'
  var sharp = document.createElement('img')
  sharp.src = 'https://webapi.amap.com/images/sharp.png'
  bottom.appendChild(sharp)
  info.appendChild(bottom)
  return info
}

//关闭信息窗体
function closeInfoWindow() {
  map.clearInfoWindow!()
}

function pushArea(name) {
  push({ path: '/area/officeArea', state: { name: name } })
}

onUnmounted(() => {
  if (map) {
    // 销毁地图实例
    map.destroy!() && map.clearEvents!('click')
  }
})
</script>

<style lang="scss" scoped>
#mapview {
  height: calc(100vh - 86px);
}

:deep(.amap-marker-label) {
  border: none !important;
}

:deep(.content-window-card) {
  position: relative;
  box-shadow: none;
  bottom: 0;
  left: 0;
  width: auto;
  padding: 0;
}

:deep(.content-window-card p) {
  height: 2rem;
}

:deep(.custom-info) {
  border: solid 1px silver;
}

:deep(div.info-top) {
  position: relative;
  background: none repeat scroll 0 0 #f9f9f9;
  border-bottom: 1px solid #ccc;
  border-radius: 5px 5px 0 0;
}

:deep(div.info-top div) {
  display: inline-block;
  color: #333333;
  font-size: 14px;
  font-weight: bold;
  line-height: 31px;
  padding: 0 10px;
}

:deep(div.info-top img) {
  position: absolute;
  top: 10px;
  right: 10px;
  transition-duration: 0.25s;
}

:deep(div.info-top img:hover) {
  box-shadow: 0px 0px 5px #000;
}

:deep(div.info-middle) {
  background-color: white;
  font-size: 12px;
  padding: 10px 6px 0px 6px;
  line-height: 20px;
}

:deep(div.info-detail) {
  background-color: white;
  color: blue;
  font-size: 12px;
  padding: 5px 0px 10px 6px;
  line-height: 20px;
}

:deep(div.info-bottom) {
  height: 0px;
  width: 100%;
  clear: both;
  text-align: center;
  position: relative;
  top: 0px;
  margin: 0 auto;
}

:deep(div.info-bottom img) {
  position: relative;
  z-index: 104;
}

:deep(span) {
  margin-left: 5px;
  font-size: 11px;
}
</style>
